
const _ = require('lodash');

class DataCenter {
	constructor() {
		this.myHeaders = new Headers();
		this.myHeaders.append('Content-Type', 'application/json');
		// this.Host = 'http://192.168.3.103:8080/graph';
		this.Host = '/graph';

		// this.analyticsHost = 'http://192.168.4.44:9999/';
		this.analyticsHost = '/';
	}

	_parse_get_params(data) {
		return _.chain(data)
			.toPairs()
			.map(i => `${i[0]}=${i[1]}`)
			.join('&')
			.value()
	}

	async _post(url, data) {
		try {
			let req = await fetch(`${this.Host}/${url}`, {
				headers: this.myHeaders,
				// credentials: 'include',
				method: 'POST',
				body: JSON.stringify(data),
			});

			let rlt = await req.json();
			
			if(rlt.status !== 'OK') {
				throw new Error('return Error');	
			}
			else{
				return rlt.body;
			}
		}
		catch(e) {
			throw e;
		}
	}

	async _get(url, data) {
		try {
			let finalUrl = '';
			if (url.indexOf('analytics/v2/api/datasource/test') !== -1) {
				finalUrl = `${this.analyticsHost}analytics/v2/api/datasource/test`;
			} else {
				finalUrl = `${this.Host}/${url}${data ? '?' : ''}${data ? data : ''}`;
			}
			let req = await fetch(finalUrl, {
				headers: this.myHeaders,
				// credentials: 'include',
			});

			let rlt = await req.json();
			if(rlt.status !== 'OK') {
				throw new Error('return Error');	
			}
			else{
				return rlt.body;
			}
		}
		catch(e) {
			throw e;
		}
	}

	async _del(url, data) {
		try {
			let finalUrl = '';
			if (url.indexOf('analytics/v2/api/datasource/test') !== -1) {
				finalUrl = `${this.analyticsHost}analytics/v2/api/datasource/test`;
			} else {
				finalUrl = `${this.Host}/${url}${data ? '?' : ''}${data ? data : ''}`;
			}
			let req = await fetch(finalUrl, {
				headers: this.myHeaders,
				method: 'DELETE'
			});

			let rlt = await req.json();
			if(rlt.status !== 'OK') {
				throw new Error('return Error');	
			}
			else{
				return rlt.body;
			}
		}
		catch(e) {
			throw e;
		}
	}

	async _get_test(url, data) {
		try {
			let finalUrl = '';
			if (url.indexOf('analytics/v2/api/datasource/test') !== -1) {
				finalUrl = `${this.analyticsHost}analytics/v2/api/datasource/test`;

			} else {
				finalUrl = `${this.Host}/${url}${data ? '?' : ''}${data ? data : ''}`;
			}
			let req = await fetch(finalUrl, {
				headers: this.myHeaders,
				// credentials: 'include',
			});

			let rlt = await req.json();
			if(rlt.return_code !== 'OK') {
				throw new Error('return Error');	
			}
			else{
				return rlt.body ? rlt.body : rlt;
			}
		}
		catch(e) {
			throw e;
		}
	}

	async getLabels() {
		try {
			let rlt = await this._get('profiling/labels');
			return rlt.labels;
		}
		catch (e) {
			console.error(e);
		}
	}

	async getPropertyKeys() {
		try {
			let rlt = await this._get('profiling/propertykeys');
			return rlt.property_keys;
		}
		catch (e) {
			console.error(e);
		}
	}

	async getRelationType() {
		try {
			let rlt = await this._get('profiling/relationship/types');
			return rlt.relationship_types;
		}
		catch (e) {
			console.error(e);
		}
	}

	async getAllRelationTypes() {
		try {
			let rlt = await this._get('profiling/relationshiptypes');
			return rlt.relationship_types;
		}
		catch (e) {
			console.error(e);
		}
	}

	async getNodes(params) {
		try {
			let rlt = await this._get('nodes', this._parse_get_params(params));
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getRelation(params) {
		try {
			let rlt = await this._get('relationships', this._parse_get_params(params));
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getP2P(params) {
		try {
			let rlt = await this._get('p2p', this._parse_get_params(params));
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getFlow(params) {
		try {
			let rlt = await this._get('moneyflow', this._parse_get_params(params));
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getAllNodesCount() {
		try {
			let rlt = await this._get('profiling/nodescount');
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getAllRelationshipsCount() {
		try {
			let rlt = await this._get('profiling/relationshipscount');
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getNodeByNodeId(nodeId) {
		try {
			let rlt = await this._get('node/' + nodeId);
			return rlt;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getRelationshipsByNodeId(nodeId) {
		try {
			let rlt = await this._get('node/' + nodeId + '/relationships');
			return rlt;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getDirectedRelationByNodeId(startNodeId, direction) {
		try {
			let rlt = await this._get('node/' + startNodeId + '/relationships/' + direction);
			return rlt;
		}
		catch (e) {
			console.log(e);
		}
	}

	async searchRelations(params) {
		try {
			let rlt = await this._get('relationships', this._parse_get_params(params));
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async advancedQueryNodes(data) {
		try {
			let rlt = await this._post('nodes', data);
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async advancedQueryRelationships(data) {
		try {
			let rlt = await this._post('relationships', data);
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async advancedQueryPath(data) {
		try {
			let rlt = await this._post('paths', data);
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getPaths(params) {
		try {
			let rlt = await this._get('paths', this._parse_get_params(params));
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getDataSourceList(params) {
		try {
			let rlt = await this._get_test(`${this.analyticsHost}analytics/v2/api/datasource/test`);

			return rlt.result;
		}
		catch (e) {
			console.log(e);
		}
	}

	async createNode(data, callback) {
		try {
			let rlt = await this._post('modeling/nodes/csv', data);
			if (callback && typeof callback == 'function') {
				callback(rlt.results);
			}
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async dropNode() {
		try {
			let rlt = await this._del('modeling/nodes');
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getListNodes(callback) {
		try {
			let rlt = await this._get('modeling/nodes');
			if (callback && typeof callback == 'function') {
				callback(rlt);
			}
			return rlt;
		} catch (e) {
			console.log(e);
		}
	}

	async getNode(id, callback) {
		try {
			let rlt = await this._get(`modeling/node/${id}`);
			if (callback && typeof callback == 'function') {
				callback(rlt.result);
			}
			return rlt.result;
		} catch (e) {
			console.log(e);
		}
	}

	async createRelationShip(data, callback) {
		try {
			let rlt = await this._post('modeling/relationships', data);
			if (callback && typeof callback == 'function') {
				callback(rlt.results);
			}
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getListRelationships() {
		try {
			let rlt = await this._get('modeling/relationships');
			return rlt;
		} catch (e) {
			console.log(e);
		}
	}

	async getRelationById(id, callback) {
		try {
			let rlt = await this._get(`modeling/relationship/${id}`);
			if (callback && typeof callback == 'function') {
				callback(rlt.result);
			}
			return rlt.result;
		} catch (e) {
			console.log(e);
		}
	}

	async dropRelationship() {
		try {
			let rlt = await this._del('modeling/relationships');
			return rlt.results;
		}
		catch (e) {
			console.log(e);
		}
	}

	async createIndex(data, callback) {
		try {
			let rlt = await this._post('modeling/nodes/index', data);
			if (callback && typeof callback == 'function') {
				callback(rlt.result);
			}
			return rlt;
		}
		catch (e) {
			console.log(e);
		}
	}

	async getTopology() {
		try {
			let rlt = await this._get('profiling/topology');
			return rlt;
		}
		catch (e) {
			console.log(e);
		}
	}
}

const dataCenter = new DataCenter();

// dataCenter.getRelation('Tom');

export default dataCenter;